package com.ming.tflitesingleblur;

import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.hardware.Camera;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;

import com.ming.tflitesingleblur.segment.Classifier;
import com.ming.tflitesingleblur.utils.ImageSaveUtils;
import com.ming.tflitesingleblur.utils.NV21ToBitmap;
import com.ming.tflitesingleblur.utils.PermissionUtils;
import com.ming.tflitesingleblur.utils.ToastUtils;

import org.tensorflow.lite.support.image.TensorImage;
import org.tensorflow.lite.task.vision.segmenter.ImageSegmenter;
import org.tensorflow.lite.task.vision.segmenter.Segmentation;

import java.io.IOException;
import java.util.List;

public class SegmentationActivity extends BaseActivity {

    private GLSurfaceView mGLSurfaceView;
    private SegmentRender mRender;


    ImageSegmenter  imageSegmenter;

    private NV21ToBitmap mNv21ToBitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gl_surface_view);
        requestNotAddFingerLayout();

        //申请权限
        PermissionUtils.requestPerssions(this, PERMISSIONS_REQUEST, PERMISSION_CAMERA, PERMISSION_STORAGE,PERMISSION_STORAGE_READ);
        if(PermissionUtils.hasPermissons(this,PERMISSION_CAMERA, PERMISSION_STORAGE, PERMISSION_STORAGE_READ)){
            initView();
        }

    }

    private void initView() {
        Log.i(TAG, "initView: ===============");
        //开启相机
        mCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
        mCamera = Camera.open(mCameraId);
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.set("orientation", "portrait");
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        parameters.setPreviewSize(mPreviewWidth, mPreviewHeight);
        mCamera.setDisplayOrientation(90);
        mCamera.setParameters(parameters);

        mCamera.setPreviewCallback(previewCallback);

        mGLSurfaceView = (GLSurfaceView) findViewById(R.id.glsurfaceview);

        //把GLSurfaceView的尺寸改成与预览尺寸比例一致,防止预览变形
        FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mGLSurfaceView.getLayoutParams();
        layoutParams.width = ImageSaveUtils.getDisplayWidth(this);
        layoutParams.height = (int) (ImageSaveUtils.getDisplayWidth(this) * (float)mPreviewWidth / (float)mPreviewHeight);
//        layoutParams.height = 500;
        mGLSurfaceView.setLayoutParams(layoutParams);
        mGLSurfaceView.requestLayout();

        //创建渲染器
        mRender = new SegmentRender(mContext, mGLSurfaceView, mCamera);

        //给GLSurfaceView设置渲染器,它要跟使用的东西同步，比如这里设置了1，那么在Render
        // 中就使用GL10，如果这里设置了2，就在Renderer中使用GL20，要对应起来
        mGLSurfaceView.setEGLContextClientVersion(2);
        mGLSurfaceView.setRenderer(mRender);
        //渲染模式
        /**
         * 1.自动模式
         setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
         2."脏"模式
         setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
         当需要重绘时，调用
         GLSurfaceView.requestRender()
         一般情况下使用脏模式，这样可以有效降低cpu负载。
         */
        mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
//        mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
        //如果上面设置的是自动模式，那只用启动一次即可，否则需要手动调用requestRender
        mGLSurfaceView.requestRender();

        handlerThread = new HandlerThread("inference");
        handlerThread.start();
        inferenceHandler = new Handler(handlerThread.getLooper());

        try {
            //这里的路径是assets中的文件路径
            imageSegmenter = ImageSegmenter.createFromFile(this, "lite-model_deeplabv3_1_metadata_2.tflite");
        } catch (IOException e) {
            e.printStackTrace();
        }

        mNv21ToBitmap = new NV21ToBitmap(mContext);

        findViewById(R.id.btn_click).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                mRender.startRecord();
                ToastUtils.showToast("开始录制");

                //延时停止录制
//                mHandler.postDelayed(new Runnable() {
//                    @Override
//                    public void run() {
//                        mRender.stopRecord();
//                        ToastUtils.showToast("录制完成");
//                    }
//                }, 5000);

            }
        });
    }



    int mCameraId;
    Camera mCamera;

    private Classifier.Model model = Classifier.Model.HUMAN_DANCE;
    private Classifier.Device device = Classifier.Device.CPU;
    private int numThreads = -1;


    private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;
    private static final String PERMISSION_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;
    private static final String PERMISSION_STORAGE_READ = Manifest.permission.READ_EXTERNAL_STORAGE;

    private static final int PERMISSIONS_REQUEST = 1;

    HandlerThread handlerThread;
    Handler inferenceHandler;

    private byte[] mNv21;
    private volatile boolean isSegment = false;
    int mPreviewWidth = 640;
    int mPreviewHeight = 480;
    private Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            if (mNv21 == null || data.length != mNv21.length) {
                mNv21 = new byte[data.length];
            }

            if(!isSegment){
                isSegment = true;
                synchronized (mNv21) {
                    System.arraycopy(data, 0, mNv21, 0, data.length);
                    inferenceHandler.post(classifyRunnable);
                }
            }
        }
    };

    String baseImagePath = "/sdcard/workspace/tfblur/";
    String inputImagePath = baseImagePath +"input/";
    String maskImagePath = baseImagePath +"mask/";
    Runnable classifyRunnable = new Runnable() {
        @Override
        public void run() {
            Bitmap bitmapImg = mNv21ToBitmap.nv21ToBitmap(mNv21,mPreviewWidth, mPreviewHeight);
            long timeStamp = System.currentTimeMillis();

            //把输入图旋转保存
//            Matrix matrix = new Matrix();
//            matrix.postRotate(90);
//            Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmapImg,
//                    bitmapImg.getWidth(),
//                    bitmapImg.getHeight(),
//                    true);
//            Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap,
//                    0, 0,
//                    scaledBitmap.getWidth(),
//                    scaledBitmap.getHeight(),
//                    matrix, true);
//
//            ImageSaveUtils.saveBitmap(rotatedBitmap,inputImage,timeStamp+".png");

//            ImageProcessingOptions.Builder imageObtionsBuilder = ImageProcessingOptions.builder();
//            imageObtionsBuilder.setOrientation(ImageProcessingOptions.Orientation.TOP_RIGHT);

            TensorImage tensorImage = TensorImage.fromBitmap(bitmapImg);

//            ImageProcessingOptions options =  imageObtionsBuilder.build();
            List<Segmentation> results = imageSegmenter.segment(tensorImage
//                    , options
            );

            //根据打印来看，segmentation数量为1，mask数量为1，coloredLabel数量为21
//            Log.i(TAG, "run: segmentation" + results.size());
//            for(int x = 0; x < results.size(); x++){
//                Segmentation segmentation = results.get(x);
//                List<ColoredLabel> colors = segmentation.getColoredLabels();
//                for(int y = 0; y < colors.size(); y++){
//                    ColoredLabel  coloredLabel = colors.get(y);
//                    Log.i(TAG, "run: coloredLabel:" + coloredLabel.toString());
//                }
//                List<TensorImage> masks = segmentation.getMasks();
////                Log.i(TAG, "run: color:"+ colors.size() + ";  masks:"+ masks.size());
//                Bitmap bitmap = masks.get(0).getBitmap();
//                ImageSaveUtils.saveBitmap(bitmap, maskImagePath,timeStamp+".png");
//            }
            //拿到mask
            Bitmap bitmap = results.get(0).getMasks().get(0).getBitmap();
            //这个mask是灰度图，但是不是0/255这种，而是240/255这种灰度图，所以需要修改,把灰色修改为黑色
            //实测为透明度不同的黑色图，背景色为0,0,0,0，主体色为15,0,0,0
            //再测发现，拿到的bitmap中，rgb像素是不可更改的，只能更改透明通道
            //所以重新复制一份，修改内部颜色
            bitmap = bitmap.copy(Bitmap.Config.ARGB_8888,true);//第二个参数表示新像素是否可以修改
            for(int i = 0; i< bitmap.getHeight(); i++){
                for(int j = 0; j< bitmap.getWidth(); j++){
                    int pixel = bitmap.getPixel(j, i);
                    if (Color.alpha(pixel) > 0){//设定为黑
                        int newPixel = Color.argb(255, 0, 0, 0);
                        bitmap.setPixel(j, i , newPixel);
                    } else {
                        int newPixel = Color.argb(255, 255, 255, 255);
                        bitmap.setPixel(j, i , newPixel);
                    }

//                    pixel = bitmap.getPixel(j, i);
//                    Log.i(TAG, "run: pixel:"
//                            + pixel +" "
//                            + Color.alpha(pixel) +" "
//                            + Color.red(pixel) +" "
//                            + Color.green(pixel)+" "
//                            + Color.blue(pixel));
                }
            }

            final Bitmap finalBitmap = bitmap;
//            ImageSaveUtils.saveBitmap(bitmap, maskImagePath,timeStamp+".png");


            mGLSurfaceView.queueEvent(new Runnable() {
                @Override
                public void run() {
                    mRender.setMaskData(finalBitmap);
                }
            });
//            Log.i(TAG, "run: "+ mask.length +" " + Arrays.toString(mask));
//            ImageSaveUtils.saveImage(maskImage,
//                    timeStamp+".png",
//                    mask,
//                    new int[]{mClassifier.getOutputWidth(),mClassifier.getImageHeight(),1},
//                    true,
//                    new float[]{0, 255f});
           //保存图片看看是什么东西
            isSegment = false;
        }
    };


    @Override
    public void onRequestPermissionsResult(
            final int requestCode, final String[] permissions, final int[] grantResults) {
        super.onRequestPermissionsResult(requestCode,permissions,grantResults);
        Log.i(TAG, "onRequestPermissionsResult: ==========" + requestCode);
        if (requestCode == PERMISSIONS_REQUEST) {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED
                    && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                //权限申请成功，重新调用一下onCreate
                onCreate(null);
            } else {
                toast("please give me permissions");
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
        }
        Log.i(TAG, "onPause=================");
    }

    @Override
    protected void onDestroy() {
        Log.i(TAG, "onDestory=================");
        super.onDestroy();
    }
}
